[% setvar title Safe Signals %]
<div id="archive-notice">
    <h3>This file is part of the Perl 6 Archive</h3>
    <p>To see what is currently happening visit <a href="http://www.perl6.org/">http://www.perl6.org/</a></p>
</div>
<div class='pod'>
<a name='TITLE'></a><h1>TITLE</h1>
<p>Safe Signals</p>
<a name='VERSION'></a><h1>VERSION</h1>
<pre>  Maintainer: Uri Guttman &lt;<a href='mailto:uri@sysarch.com'>uri@sysarch.com</a>&gt;
  Date: 7 Aug 2000
  Mailing List: <a href='mailto:perl6-language-flow@perl.org'>perl6-language-flow@perl.org</a>
  Number: 60
  Version: 1
  Status: Developing</pre>
<a name='ABSTRACT'></a><h1>ABSTRACT</h1>
<p>This RFC describes how Perl6 can support safe signals with multiple
techniques.</p>
<a name='DESCRIPTION'></a><h1>DESCRIPTION</h1>
<p>Perl5 suffers from its well know unsafe signal handling. It is due to
the asynchronous way signals are triggered at the level of C
code. A signal could be delivered in Perl while some critical operation
(e.g. malloc) is happening and all hell breaks loose. Signals have to be
delivered synchronously with respect Perl op code dispatching.</p>
<a name='IMPLEMENTATION'></a><h1>IMPLEMENTATION</h1>
<p>There are multiple ways to support safe signals and they can all easily
be supported. Here are the most common ways and various techniques which
make handling signals easier.</p>
<a name='In-line Code'></a><h2>In-line Code</h2>
<p>If you have only a single linear thread of code and want safe signals,
you have to pay the penalty of checking for them in between Perl op
codes. This requires the Perl compiler to insert signal checking op at
regular intervals in the op tree.  This can be done every N ops with N
being some special global value. The code to do the test can be done
in-line in the main dispatch loop and be very fast. The actual C handlers
will just be like the ones in the event loop and just bump counters and
set flags.</p>
<p>Enabling in-line testing for signals can also be a compile time option
so a selected section of of a thread could be where the test are
inserted.</p>
<p>Here is a possible pragma to enable this:</p>
<p>use signal in-line =&gt; 10 ;</p>
<p>Then you can just create callbacks for any signal as shown below.</p>
<a name='Mailboxes'></a><h2>Mailboxes</h2>
<p>A mailbox is a combination of a semaphore and a queue/pipe. It is a
clean way to send messages between threads. A special mailbox for
signals can be created which can be tested and blocked upon. The data
read from the mailbox will be the signal name and any other info
attached to the signal. Any thread (including a single thread) can
synchornously test for signals under program control. This is how a
progrom would poll for signals.</p>
<a name='Event Loops'></a><h2>Event Loops</h2>
<p>Event loops support safe signals by delivering them synchronously with
the dispatch of other callbacks. Then the signal callback cannot collide
with any others. This is currently being done in Event.pm (and i think
Perl/Tk's event loop is similar here).</p>
<a name='Threads'></a><h2>Threads</h2>
<p>Threads can work with signals in two ways. First, one or more threads
can run event loops and their signal handlers are safe and can do work
or communicate with other threads. Second, any thread can block on the
special signal mailbox. When the signal is delivered, the blocked thread
can continue safely and can then do the work for that signal.</p>
<a name='Callbacks'></a><h2>Callbacks</h2>
<p>This pragma would use the same callback interface as all the new I/O
objects would. This consistancy of callback style in the language is a
major win here.  Since someone mentioned any default Perl callback names
be in caps, will go with that here.  Again the default method names
would be carefully chosen to be easy to remember and use,
e.g. SIGHUP_RECEIVED and SIGHUP_TIMEOUT would be the ones for the above
example if the callback value was an object or a class.</p>
<a name='Timeouts'></a><h2>Timeouts</h2>
<p>By using the general callback API, signals now can have builtin
timeouts. This simplifies some tasks which need to do work on a schedule
and also when you need it, e.g. checkpointing. If this were
triggered by SIGHUP, then it could be set to timeout every minute and
the callback would execute if there hasn't seen any HUPs in that period.</p>
<a name='use signal pragma'></a><h2>use signal pragma</h2>
<p>I propose a pragma which would make creating signal callback more of a
top level operation and remove the need for the %SIG hash. The pragma
would be stackable so you could override a handler inside a code block.</p>
<p>It would be something like this:</p>
<p># Here is a main line code callback with a sub ref and timeout
# the timeout will call the sub SIGHUP_TIMEOUT in this current package.</p>
<p>use signal name =&gt; 'SIGHUP', cb =&gt; \&amp;hup_handler, timeout =&gt; 3600 ;
sub hup_handler { print &quot;They hupped me! Bastards!!&quot; }</p>
<p># Here is a class level callback with the default callback name</p>
<p>use signal name =&gt; 'SIGINT', cb =&gt; __PACKAGE__ ;
sub SIGINT_HANDLER { print &quot;They killed me! Bastards!!&quot; }</p>
<p># Here is a object callback with the a custom callback name</p>
<p>my $foo = Bar-&gt;new() ;
use signal name =&gt; 'SIGCANCEL', cb =&gt; $foo, method = 'cancel_handler' ;
sub Bar::cancel_handler { print &quot;They cancelled me! Bastards!!&quot; }</p>
<a name='IMPACT'></a><h1>IMPACT</h1>
<p>People will stop bitching about perl not having safe signals.</p>
<a name='UNKNOWNS'></a><h1>UNKNOWNS</h1>
<a name='REFERENCES'></a><h1>REFERENCES</h1>
<p>Event.pm		- XS based event loop module.</p>
<p>RFC #1			- Implementation of Threads in Perl</p>
<p>RFC #47			- Universal Asynch I/O (the moby one)</p>
<p>%SIG			- perlvar</p>
</div>
